{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Sets 各种集合\n",
    "\n",
    "## Basic Sets 基本集合\n",
    "\n",
    "### Set 集合\n",
    "\n",
    "#### 类 class sympy.sets.sets.Set(*args)\n",
    "\n",
    "任何类型集合的基类。\n",
    "\n",
    "##### 解释\n",
    "\n",
    "这并不意味着直接作为一个项目的容器使用。它的行为与内置集不同; 请参见 有限级 `FiniteSet`。\n",
    "\n",
    "实数区间由 `Interval` 类表示，集合由 `Union` 类表示。空集由 `EmptySet` 类表示，作为单例可以使用 `S.EmptySet`。\n",
    "\n",
    "##### 属性 boundary 边界\n",
    "\n",
    "集合的边界。\n",
    "\n",
    "###### 解释\n",
    "\n",
    "点 `x` 在集合 `S` 的边界上，如果\n",
    "\n",
    "1. `x` 是 `S` 的闭包，即 `x` 的每个邻居都包含 `S` 中的一个点。\n",
    "\n",
    "2. `x` 不在 `S` 的内部。不存在完全包含在 `S` 中的以 `x` 为中心的开集。\n",
    "\n",
    "`S`的外缘上有点。如果 `S` 是开的，那么这些点实际上不需要包含在 `S` 中。\n",
    "\n",
    "例如，区间的边界是它的起点和终点。不管间隔是否打开，这都是正确的。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{0, 1}\n",
      "{0, 1}\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 1).boundary)\n",
    "print(Interval(0, 1, True, False).boundary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 closure 闭包\n",
    "\n",
    "属性方法，该方法返回集合的闭包。闭包被定义为集合本身及其边界的并集。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Reals\n",
      "Interval(0, 1)\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval\n",
    "print(S.Reals.closure)\n",
    "print(Interval(0, 1).closure)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 complement(universe)\n",
    "The complement of ‘self’ w.r.t the given universe.\n",
    "\n",
    "`self`的补语`complement`是对既定`universe`的补语。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Union(Interval.open(-oo, 0), Interval.open(1, oo))\n",
      "Complement(UniversalSet, Interval(0, 1))\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, S\n",
    "print(Interval(0, 1).complement(S.Reals))\n",
    "print(Interval(0, 1).complement(S.UniversalSet))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 contains(other)\n",
    "\n",
    "返回一个 `SymPy` 值，该值指示是否在 `self` 中包含 `other`: 如果是返回 `true`，否则为 `false`，否则为一个未计算的 `Contains` 表达式(或者，如 `ConditionSet` 和 `FiniteSet/interval` 的联合，则为一个表达式，指示包含的条件)。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\text{True}$"
      ],
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 78,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval, S\n",
    "from sympy.abc import x\n",
    "Interval(0, 1).contains(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "作为一种快捷方式，可以使用 `in` 操作符，但是如果没有得到确定的 `true` 或 `false`，将引起抛出错误。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(0 <= x) & (x <= 1)\n"
     ]
    },
    {
     "ename": "TypeError",
     "evalue": "did not evaluate to a bool: (0 <= x) & (x <= 1)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [79]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28mprint\u001b[39m(Interval(\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m1\u001b[39m)\u001b[38;5;241m.\u001b[39mcontains(x))\n\u001b[0;32m----> 2\u001b[0m \u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mInterval\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/sets.py:702\u001b[0m, in \u001b[0;36mSet.__contains__\u001b[0;34m(self, other)\u001b[0m\n\u001b[1;32m    698\u001b[0m b \u001b[38;5;241m=\u001b[39m tfn[c]\n\u001b[1;32m    699\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m b \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m    700\u001b[0m     \u001b[38;5;66;03m# x in y must evaluate to T or F; to entertain a None\u001b[39;00m\n\u001b[1;32m    701\u001b[0m     \u001b[38;5;66;03m# result with Set use y.contains(x)\u001b[39;00m\n\u001b[0;32m--> 702\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mdid not evaluate to a bool: \u001b[39m\u001b[38;5;132;01m%r\u001b[39;00m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m c)\n\u001b[1;32m    703\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m b\n",
      "\u001b[0;31mTypeError\u001b[0m: did not evaluate to a bool: (0 <= x) & (x <= 1)"
     ]
    }
   ],
   "source": [
    "print(Interval(0, 1).contains(x))\n",
    "x in Interval(0, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`in` 的结果是 `bool`，而不是 `SymPy` 值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(1 in Interval(0, 2))\n",
    "print(_ is S.true)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 inf\n",
    "The  of self.\n",
    "\n",
    "`self` 的下限 `infimum`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, Union\n",
    "print(Interval(0, 1).inf)\n",
    "print(Union(Interval(0, 1), Interval(2, 3)).inf)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 interior\n",
    "\n",
    "属性方法，该方法返回集的内部`interior`。集合 `S` 的内部包含所有不属于 `S` 的边界的 `S` 点。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval.open(0, 1)\n",
      "EmptySet\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 1).interior)\n",
    "print(Interval(0, 1).boundary.interior)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 intersect(other)\n",
    "Returns the intersection of ‘self’ and ‘other’.\n",
    "\n",
    "返回 `self` 和 `other`的交集。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(1, 2)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\emptyset$"
      ],
      "text/plain": [
       "EmptySet"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(1, 3).intersect(Interval(1, 2)))\n",
    "from sympy import imageset, Lambda, symbols, S\n",
    "n, m = symbols('n m')\n",
    "a = imageset(Lambda(n, 2*n), S.Integers)\n",
    "a.intersect(imageset(Lambda(m, 2*m + 1), S.Integers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 intersection(other)\n",
    "\n",
    "`intersect()` 的别名\n",
    "\n",
    "##### 属性 is_closed\n",
    "\n",
    "用于检查集合是否封闭的属性方法。\n",
    "\n",
    "###### 解释\n",
    "\n",
    "如果集合的补集 `complement` 是开集 `open`，则集合是闭集合 `closed`。实数集 `reals`自己的关闭性 `closedness`取决于`R`的respect及其标准拓扑。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "Interval(0, 1).is_closed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 is_disjoint(other)\n",
    "\n",
    "如果`self`和`other`不相交`disjoint`，则返回 True。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 2).is_disjoint(Interval(1, 2)))\n",
    "print(Interval(0, 2).is_disjoint(Interval(3, 4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### 参考资料\n",
    "\n",
    "[R739] https://en.wikipedia.org/wiki/Disjoint_set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 is_open\n",
    "Property method to check whether a set is open.\n",
    "\n",
    "属性检查集合是否开放。\n",
    "\n",
    "###### 解释\n",
    "\n",
    "一个集合是开的`open`当且仅当它与其边界有一个空的交集。特别地，实数的子集 `A` 是开的当且仅当它的每个点都包含在一个开区间中，这个开区间是 `A` 的子集。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import S\n",
    "print(S.Reals.is_open)\n",
    "print(S.Rationals.is_open)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 is_proper_subset(other)\n",
    "\n",
    "如果 `self` 是 `other` 的真子集`proper subset`，则返回 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 0.5).is_proper_subset(Interval(0, 1)))\n",
    "print(Interval(0, 1).is_proper_subset(Interval(0, 1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 is_proper_superset(other)\n",
    "\n",
    "如果 `self` 是他人的真超集`proper superset`，则返回 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 1).is_proper_superset(Interval(0, 0.5)))\n",
    "print(Interval(0, 1).is_proper_superset(Interval(0, 1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 is_subset(other)\n",
    "\n",
    "如果 `self` 是 `other` 的子集`subset`，则返回 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 0.5).is_subset(Interval(0, 1)))\n",
    "print(Interval(0, 1).is_subset(Interval(0, 1, left_open=True)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 is_superset(other)\n",
    "\n",
    "如果 `self` 是他人的超集`superset`，则返回 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 0.5).is_superset(Interval(0, 1)))\n",
    "print(Interval(0, 1).is_superset(Interval(0, 1, left_open=True)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 isdisjoint(other)\n",
    "\n",
    "is_disjoint() 的别名\n",
    "\n",
    "##### 方法 issubset 等子集(other 其他)\n",
    "\n",
    "is_subset()  的别名\n",
    "\n",
    "##### 方法 issuperset 有问题的人(other 其他)\n",
    "\n",
    "is_superset()  的别名\n",
    "\n",
    "##### 属性 measure 度量\n",
    "\n",
    "`self`的(Lebesgue)测量。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, Union\n",
    "print(Interval(0, 1).measure)\n",
    "print(Union(Interval(0, 1), Interval(2, 3)).measure)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 powerset()\n",
    "\n",
    "找到`self`的幂集。\n",
    "\n",
    "###### 例子\n",
    "\n",
    "空集的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{\\emptyset\\right\\}$"
      ],
      "text/plain": [
       "{EmptySet}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import EmptySet, FiniteSet, Interval\n",
    "A = EmptySet\n",
    "A.powerset()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有限集的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = FiniteSet(1, 2)\n",
    "a, b, c = FiniteSet(1), FiniteSet(2), FiniteSet(1, 2)\n",
    "A.powerset() == FiniteSet(a, b, c, EmptySet)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个间隔的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathcal{P}\\left(\\left[1, 2\\right]\\right)$"
      ],
      "text/plain": [
       "PowerSet(Interval(1, 2))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Interval(1, 2).powerset()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### 参考资料\n",
    "\n",
    "[R740] https://en.wikipedia.org/wiki/Power_set\n",
    "\n",
    "##### 属性 sup 上确界\n",
    "\n",
    "`self`的上确界\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, Union\n",
    "print(Interval(0, 1).sup)\n",
    "print(Union(Interval(0, 1), Interval(2, 3)).sup)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 函数 symmetric_difference(other)\n",
    "\n",
    "返回`self`和他人的对称差。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Union(Interval.open(-oo, 1), Interval.open(3, oo))\n",
      "Union(Interval.open(-oo, 1), Interval.open(10, oo))\n",
      "Reals\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, S\n",
    "from sympy import S, EmptySet\n",
    "print(Interval(1, 3).symmetric_difference(S.Reals))\n",
    "print(Interval(1, 10).symmetric_difference(S.Reals))\n",
    "print(S.Reals.symmetric_difference(EmptySet))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 参考资料\n",
    "\n",
    "[R741] https://en.wikipedia.org/wiki/Symmetric_difference\n",
    "\n",
    "##### 方法 union(other)\n",
    "\n",
    "返回`self`与`other`的并集`union`。\n",
    "\n",
    "###### 例子\n",
    "\n",
    "作为一个更快捷方式，可以使用 `+` 操作符:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Union(Interval(0, 1), Interval(2, 3))\n",
      "Union(Interval(0, 1), Interval(2, 3))\n",
      "Union({3}, Interval.Lopen(1, 2))\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, FiniteSet\n",
    "print(Interval(0, 1).union(Interval(2, 3)))\n",
    "print(Interval(0, 1) + Interval(2, 3))\n",
    "print(Interval(1, 2, True, True) + FiniteSet(2, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类似地，对于集合差异也可以使用`-`操作符:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval.Lopen(1, 2)\n",
      "Union(Interval.Ropen(1, 2), Interval.Lopen(2, 3))\n"
     ]
    }
   ],
   "source": [
    "print(Interval(0, 2) - Interval(0, 1))\n",
    "print(Interval(1, 3) - FiniteSet(2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 sympy.sets.sets.imageset(*args)\n",
    "\n",
    "在变换 `f` 下返回一个集合的映射`image`。\n",
    "\n",
    "###### 解释\n",
    "\n",
    "如果此函数无法计算图像`image`，则返回未计算的 `ImageSet` 对象。\n",
    "\n",
    "###### 例子\n",
    "\n",
    "$$ \\{ f(x) \\mid x \\in \\mathrm{self} \\} $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(0, 4)\n",
      "Interval(0, 4)\n",
      "ImageSet(Lambda(x, sin(x)), Interval(-2, 1))\n",
      "ImageSet(Lambda(x, sin(x)), Interval(-2, 1))\n",
      "ImageSet(Lambda(y, x + y), Interval(-2, 1))\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval, imageset, sin, Lambda\n",
    "from sympy.abc import x\n",
    "print(imageset(x, 2*x, Interval(0, 2)))\n",
    "print(imageset(lambda x: 2*x, Interval(0, 2)))\n",
    "print(imageset(Lambda(x, sin(x)), Interval(-2, 1)))\n",
    "print(imageset(sin, Interval(-2, 1)))\n",
    "print(imageset(lambda y: x + y, Interval(-2, 1)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "应用于整数集合的表达式被简化以显示尽可能少的负数，线性表达式被转换成标准形式。如果这是不可取的，那么应该使用未计算的 `ImageSet`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ImageSet(Lambda(x, 2*x + 1), Integers)\n"
     ]
    }
   ],
   "source": [
    "print(imageset(x, -2*x + 5, S.Integers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Elementary Sets 初等集\n",
    "\n",
    "### Interval 时间段\n",
    "\n",
    "#### 类 class sympy.sets.sets.Interval(start, end, left_open=False, right_open=False)\n",
    "\n",
    "将实际间隔表示为集合。\n",
    "\n",
    "##### 用法:\n",
    "\n",
    "- 返回一个带有开始点和结束点的间隔。\n",
    "\n",
    "- 对于 `left_open = True` (默认的 `left_open=False`) `，interval` 将在左侧打开。类似地，对于 `right_open=True`，`interval`将在右侧打开。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(0, 1)\n",
      "Interval.Ropen(0, 1)\n",
      "Interval.Lopen(0, 1)\n",
      "Interval.open(0, 1)\n",
      "Interval(0, a)\n"
     ]
    }
   ],
   "source": [
    "from sympy import Symbol, Interval\n",
    "print(Interval(0, 1))\n",
    "print(Interval.Ropen(0, 1))\n",
    "print(Interval.Lopen(0, 1))\n",
    "print(Interval.open(0, 1))\n",
    "a = Symbol('a', real=True)\n",
    "print(Interval(0, a))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 注释\n",
    "\n",
    "只支持实型的端点\n",
    "\n",
    "`a > b` 的情况下`Interval(a，b)`将返回空集\n",
    "\n",
    "Use the evalf() method to turn an Interval into an mpmath mpi interval instance\n",
    "\n",
    "使用 `evalf()`方法将 `Interval` 转换为 `mpmath` 的 `mpi` `Interval` 实例\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R742] https://en.wikipedia.org/wiki/Interval_%28mathematics%29\n",
    "\n",
    "##### classmethod Lopen(a, b)\n",
    "\n",
    "返回不包含左边界的间隔。\n",
    "\n",
    "##### classmethod Ropen(a, b)\n",
    "\n",
    "返回不包含右边界的区间。\n",
    "\n",
    "##### 方法 as_relational(x)\n",
    "\n",
    "用不等式和逻辑运算符重写区间。\n",
    "\n",
    "##### 属性 end 结束\n",
    "\n",
    "间隔`Interval`的右侧端点。\n",
    "\n",
    "此属性取值与 `sup` 属性相同。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 1$"
      ],
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "Interval(0, 1).end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 is_left_unbounded\n",
    "\n",
    "如果左端点为负无穷大，则返回 `True`。\n",
    "\n",
    "##### 属性 is_right_unbounded\n",
    "\n",
    "如果右端点为正无穷大，则返回 `True`。\n",
    "\n",
    "##### 属性 left_open 左边开着\n",
    "\n",
    "如果 interval 是左开的，则为 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 1, left_open=True).left_open)\n",
    "print(Interval(0, 1, left_open=False).left_open)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### classmethod open(a, b)\n",
    "\n",
    "返回一个不包含任何边界的区间。\n",
    "\n",
    "##### 属性 right_open\n",
    "\n",
    "如果 `interval` 是右开的，则为 `True`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "print(Interval(0, 1, right_open=True).right_open)\n",
    "print(Interval(0, 1, right_open=False).right_open)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 start 开始\n",
    "\n",
    "间隔的左端点。\n",
    "\n",
    "此属性的值与 `inf` 属性的值相同。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 0$"
      ],
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "Interval(0, 1).start"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## FiniteSet 有限集\n",
    "\n",
    "### 类 class sympy.sets.sets.FiniteSet Finestet(*args, **kwargs)\n",
    "\n",
    "表示有限的离散数字集。\n",
    "\n",
    "#### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{1, 2, 3, 4}\n",
      "True\n",
      "{1, 2, 3, 4}\n",
      "{1, 3, 4}\n",
      "{1, 2, 3, 4, 5}\n"
     ]
    }
   ],
   "source": [
    "from sympy import FiniteSet\n",
    "print(FiniteSet(1, 2, 3, 4))\n",
    "print(3 in FiniteSet(1, 2, 3, 4))\n",
    "members = [1, 2, 3, 4]\n",
    "f = FiniteSet(*members)\n",
    "print(f)\n",
    "print(f - FiniteSet(2))\n",
    "print(f + FiniteSet(2, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 参考资料\n",
    "\n",
    "[R743] https://en.wikipedia.org/wiki/Finite_set\n",
    "\n",
    "#### 方法 as_relational(symbol)\n",
    "\n",
    "在等式和逻辑运算符方面重写有限元素集。\n",
    "\n",
    "## Compound Sets 复合集\n",
    "\n",
    "### Union 并集\n",
    "\n",
    "#### 类 class sympy.sets.sets.Union(*args, **kwargs)\n",
    "\n",
    "表示集合的并集作为集合。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[1, 2\\right] \\cup \\left[3, 4\\right]$"
      ],
      "text/plain": [
       "Union(Interval(1, 2), Interval(3, 4))"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Union, Interval\n",
    "Union(Interval(1, 2), Interval(3, 4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果可能的话，Union 构造函数将总是尝试合并重叠的间隔。例如:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[1, 3\\right]$"
      ],
      "text/plain": [
       "Interval(1, 3)"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Union(Interval(1, 2), Interval(2, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 Intersection\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R744] https://en.wikipedia.org/wiki/Union_%28set_theory%29\n",
    "\n",
    "#### 函数 as_relational(symbol)\n",
    "\n",
    "在等式和逻辑运算符方面重写一个并集。\n",
    "\n",
    "### Intersection 交集\n",
    "\n",
    "#### 类 class sympy.sets.sets.Intersection(*args, **kwargs)\n",
    "\n",
    "表示集合的交集。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left[2, 3\\right]$"
      ],
      "text/plain": [
       "Interval(2, 3)"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Intersection, Interval\n",
    "Intersection(Interval(1, 3), Interval(2, 4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 Union\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R745] https://en.wikipedia.org/wiki/Intersection_%28set_theory%29\n",
    "\n",
    "##### as_relational(symbol)\n",
    "\n",
    "根据等式和逻辑运算符改写交集\n",
    "\n",
    "### ProductSet 笛卡尔集\n",
    "\n",
    "#### 类 class sympy.sets.sets.ProductSet(*sets, **assumptions)\n",
    "\n",
    "表示集合的笛卡儿积。\n",
    "\n",
    "##### 解释\n",
    "\n",
    "返回给定多个集合，它们可以是迭代的，也可以是单个的参数的笛卡儿积/值。\n",
    "\n",
    "可以在任何集合上使用 * 操作符以方便速记。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProductSet(Interval(0, 5), {1, 2, 3})\n",
      "True\n",
      "ProductSet(Interval(0, 1), Interval(0, 1))\n",
      "{(H, T), (H, H), (T, T), (T, H)}\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, FiniteSet, ProductSet\n",
    "I = Interval(0, 5); S = FiniteSet(1, 2, 3)\n",
    "print(ProductSet(I, S))\n",
    "print((2, 2) in ProductSet(I, S))\n",
    "print(Interval(0, 1) * Interval(0, 1)) # The unit square\n",
    "coin = FiniteSet('H', 'T')\n",
    "print(set(coin**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "笛卡儿积不是交换的或结合的，例如:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "print(I*S == S*I)\n",
    "print((I*I)*I == I*(I*I))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 注释\n",
    "\n",
    "将大多数操作传递给参数集\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R746] https://en.wikipedia.org/wiki/Cartesian_product\n",
    "\n",
    "##### 属性 is_iterable\n",
    "\n",
    "测试集合是否可迭代的属性方法。如果 `set` 是可迭代的，则返回 `True`，否则返回 `False`。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import FiniteSet, Interval\n",
    "I = Interval(0, 1)\n",
    "A = FiniteSet(1, 2, 3, 4, 5)\n",
    "print(I.is_iterable)\n",
    "print(A.is_iterable)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Complement 补体\n",
    "\n",
    "#### 类 class sympy.sets.sets.Complement(a, b, evaluate=True)\n",
    "\n",
    "表示集合与另一集合的集合差或相对补集。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{0, 2\\right\\}$"
      ],
      "text/plain": [
       "{0, 2}"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Complement, FiniteSet\n",
    "Complement(FiniteSet(0, 1, 2), FiniteSet(1))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 Intersection, Union\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R747] http://mathworld.wolfram.com/ComplementSet.html\n",
    "\n",
    "##### as_relational(symbol)\n",
    "\n",
    "在等式和逻辑运算符方面重写一个补集\n",
    "\n",
    "##### static reduce(A, B)\n",
    "\n",
    "简化补集\n",
    "\n",
    "### SymmetricDifference 对称差分\n",
    "\n",
    "#### 类 class sympy.sets.sets.SymmetricDifference(a, b, evaluate=True)\n",
    "\n",
    "表示位于两个集合之一而不在其交集中的元素集。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{1, 2, 4, 5\\right\\}$"
      ],
      "text/plain": [
       "{1, 2, 4, 5}"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import SymmetricDifference, FiniteSet\n",
    "SymmetricDifference(FiniteSet(1, 2, 3), FiniteSet(3, 4, 5))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 Complement, Union\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R748] https://en.wikipedia.org/wiki/Symmetric_difference\n",
    "\n",
    "##### 方法 as_relational(symbol)\n",
    "\n",
    "在等式和逻辑运算符方面重写对称差异\n",
    "\n",
    "## Singleton Sets 单件集\n",
    "\n",
    "### EmptySet 空集\n",
    "\n",
    "#### 类 class sympy.sets.sets.EmptySet\n",
    "\n",
    "表示空集。空集作为单例可用。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "EmptySet\n",
      "EmptySet\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval\n",
    "print(S.EmptySet)\n",
    "print(Interval(1, 2).intersect(S.EmptySet))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 UniversalSet\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R749] https://en.wikipedia.org/wiki/Empty_set\n",
    "\n",
    "### UniversalSet 全集\n",
    "\n",
    "#### 类 class sympy.sets.sets.UniversalSet\n",
    "\n",
    "表示所有事物的集合。通用集合作为单例可用，即 S.UniversalSet。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "UniversalSet\n",
      "Interval(1, 2)\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval\n",
    "print(S.UniversalSet)\n",
    "print(Interval(1, 2).intersect(S.UniversalSet))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 EmptySet\n",
    "\n",
    "##### 参考资料\n",
    "\n",
    "[R750] https://en.wikipedia.org/wiki/Universal_set\n",
    "\n",
    "## Special Sets 特定集\n",
    "\n",
    "### Naturals 自然数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Naturals\n",
    "\n",
    "表示自然数(或计数数) ，它们都是从1开始的正整数。这一套也可以作为单体 S.Naturals。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "1\n",
      "2\n",
      "3\n",
      "{1, 2, …, 10}\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval, pprint\n",
    "print(5 in S.Naturals)\n",
    "iterable = iter(S.Naturals)\n",
    "print(next(iterable))\n",
    "print(next(iterable))\n",
    "print(next(iterable))\n",
    "pprint(S.Naturals.intersect(Interval(0, 10)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见\n",
    "> - Naturals0: 非负整数(即也包括0)\n",
    "> - Integers: 也包括负整数\n",
    "\n",
    "### Naturals0 包含0的自然数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Naturals0\n",
    "\n",
    "表示所有非负整数的整数，包括零。\n",
    "\n",
    "> 参见\n",
    "> - Naturals: 正整数; 不包括0\n",
    "> - Integers: 也包括负整数\n",
    "\n",
    "### Integers 整数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Integers \n",
    "\n",
    "表示所有整数: 正数、负数和零。这个集合也可以作为单个 `S.Integers`。\n",
    "\n",
    "#### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "0\n",
      "1\n",
      "-1\n",
      "2\n",
      "{-4, -3, …, 4}\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Interval, pprint\n",
    "print(5 in S.Naturals)\n",
    "iterable = iter(S.Integers)\n",
    "print(next(iterable))\n",
    "print(next(iterable))\n",
    "print(next(iterable))\n",
    "print(next(iterable))\n",
    "pprint(S.Integers.intersect(Interval(-4, 4)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 \n",
    "> - Naturals0: 非负整数\n",
    "> - Integers: 正负整数和零\n",
    "\n",
    "### Reals 实数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Reals \n",
    "\n",
    "表示从负无穷到正无穷的所有实数，包括所有整数、有理数和无理数。这个集合也可以作为单例 `S.Reals` 提供。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "True\n",
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, Rational, pi, I\n",
    "print(5 in S.Reals)\n",
    "print(Rational(-1, 2) in S.Reals)\n",
    "print(pi in S.Reals)\n",
    "print(3*I in S.Reals)\n",
    "print(S.Reals.contains(pi))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 ComplexRegion 复杂区域\n",
    "\n",
    "### Complexes 复数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Complexes \n",
    "\n",
    "所有复数的集合\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Complexes\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import S, I\n",
    "print(S.Complexes)\n",
    "print(1 + I in S.Complexes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 Reals, ComplexRegion\n",
    "\n",
    "### ImageSet 虚数集\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.ImageSet(flambda, *sets)\n",
    "\n",
    "集合在数学函数下的形象。变换必须作为一个 `Lambda` 函数给出，该函数的参数数量与它运算的集合的元素数量一样多，例如，当作用于一组整数时，1个参数; 当作用于一个复杂区域时，2个参数。\n",
    "\n",
    "这个函数通常不直接调用，而是从 `imageset` 调用。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "{1, 4, 9}\n",
      "1\n",
      "4\n",
      "9\n",
      "16\n"
     ]
    }
   ],
   "source": [
    "from sympy import Symbol, S, pi, Dummy, Lambda\n",
    "from sympy import FiniteSet, ImageSet, Interval\n",
    "x = Symbol('x')\n",
    "N = S.Naturals\n",
    "squares = ImageSet(Lambda(x, x**2), N) # {x**2 for x in N}\n",
    "print(4 in squares)\n",
    "print(5 in squares)\n",
    "print(FiniteSet(0, 1, 2, 3, 4, 5, 6, 7, 9, 10).intersect(squares))\n",
    "square_iterable = iter(squares)\n",
    "for i in range(4):\n",
    "    print(next(square_iterable))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果你想得到 x= 2或1/2等(请检查X值在传递为参数之前是否在 `base_set` 中)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4\n",
      "1/4\n",
      "{0}\n"
     ]
    }
   ],
   "source": [
    "print(squares.lamda(2))\n",
    "print(squares.lamda(S(1)/2))\n",
    "n = Dummy('n')\n",
    "solutions = ImageSet(Lambda(n, n*pi), S.Integers) # solutions of sin(x) = 0\n",
    "dom = Interval(-1, 1)\n",
    "print(dom.intersect(solutions))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 sympy.sets.sets.imageset\n",
    "\n",
    "### Range 范围\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.Range(*args)\n",
    "\n",
    "表示一个整数范围。可以调用为 `Range(stop)` ，`Range(start，stop)` ，或 `Range(start, stop, step)` ; `step`默认值为1。\n",
    "\n",
    "`Range(stop)`与 `Range(0， stop， 1)`相同，而 `stop` 值(就像 Python Range 一样)不包含在 `Range` 值中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 2]\n",
      "[10, 8, 6, 4, 2]\n"
     ]
    }
   ],
   "source": [
    "from sympy import Range\n",
    "print(list(Range(3)))\n",
    "print(list(Range(10, 0, -2)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "允许无限的范围。`oo` 和`-oo` 从不包含在集合中(`Range` 始终是 `Integers` 的子集)。如果起始点是无限的，那么最终的值是 `stop - step`。为了迭代这样一个范围，它需要被反转:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n"
     ]
    }
   ],
   "source": [
    "from sympy import oo\n",
    "r = Range(-oo, 1)\n",
    "print(r[-1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "Cannot iterate over Range with infinite start",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [42]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;28;43miter\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mr\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/fancysets.py:732\u001b[0m, in \u001b[0;36mRange.__iter__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    730\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot iterate over symbolic Range\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m    731\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstart \u001b[38;5;129;01min\u001b[39;00m [S\u001b[38;5;241m.\u001b[39mNegativeInfinity, S\u001b[38;5;241m.\u001b[39mInfinity]:\n\u001b[0;32m--> 732\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCannot iterate over Range with infinite start\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m    733\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstart \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstop:\n\u001b[1;32m    734\u001b[0m     i \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstart\n",
      "\u001b[0;31mTypeError\u001b[0m: Cannot iterate over Range with infinite start"
     ]
    }
   ],
   "source": [
    "next(iter(r))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle 0$"
      ],
      "text/plain": [
       "0"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(iter(r.reversed))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "虽然 Range 是一个 Set (并且支持正常的 Set 操作) ，但它维护元素的顺序，并且可以在将要使用 Range 的上下文中使用。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Range(4, 8, 2)\n",
      "[4, 6]\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval\n",
    "x = Range(0, 10, 2).intersect(Interval(3, 7))\n",
    "print(x)\n",
    "print(list(x))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "虽然范围切片总是返回一个范围(可能是空的) ，但是空集将从任何空的交集返回:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Range(0, 0, 1)\n",
      "EmptySet\n",
      "EmptySet\n"
     ]
    }
   ],
   "source": [
    "print(Range(3)[:0])\n",
    "print(Range(3).intersect(Interval(4, oo)))\n",
    "print(Range(3).intersect(Range(4, oo)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以接受符号参数，但是除了显示 Range 之外，对其他操作的支持非常有限:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i\n"
     ]
    },
    {
     "ename": "ValueError",
     "evalue": "cannot tell if Range is null or not",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Input \u001b[0;32mIn [47]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msympy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mabc\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m i, j, k\n\u001b[1;32m      3\u001b[0m \u001b[38;5;28mprint\u001b[39m(Range(i, j, k)\u001b[38;5;241m.\u001b[39mstart)\n\u001b[0;32m----> 4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mRange\u001b[49m\u001b[43m(\u001b[49m\u001b[43mi\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mj\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mk\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minf\u001b[49m)\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/sets.py:274\u001b[0m, in \u001b[0;36mSet.inf\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    259\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m    260\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21minf\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m    261\u001b[0m     \u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m    262\u001b[0m \u001b[38;5;124;03m    The infimum of ``self``.\u001b[39;00m\n\u001b[1;32m    263\u001b[0m \n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m    272\u001b[0m \n\u001b[1;32m    273\u001b[0m \u001b[38;5;124;03m    \"\"\"\u001b[39;00m\n\u001b[0;32m--> 274\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_inf\u001b[49m\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/fancysets.py:941\u001b[0m, in \u001b[0;36mRange._inf\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    939\u001b[0m \u001b[38;5;129m@property\u001b[39m\n\u001b[1;32m    940\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_inf\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 941\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mself\u001b[39m:\n\u001b[1;32m    942\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m S\u001b[38;5;241m.\u001b[39mEmptySet\u001b[38;5;241m.\u001b[39minf\n\u001b[1;32m    943\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhas(Symbol):\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/fancysets.py:795\u001b[0m, in \u001b[0;36mRange.__bool__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    793\u001b[0m b \u001b[38;5;241m=\u001b[39m is_eq(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstart, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mstop)\n\u001b[1;32m    794\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m b \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 795\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mcannot tell if Range is null or not\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m    796\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mbool\u001b[39m(b)\n",
      "\u001b[0;31mValueError\u001b[0m: cannot tell if Range is null or not"
     ]
    }
   ],
   "source": [
    "from sympy import Symbol, pprint\n",
    "from sympy.abc import i, j, k\n",
    "print(Range(i, j, k).start)\n",
    "print(Range(i, j, k).inf)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用整数符号会获得更好的成功:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "n\n",
      "{n, n + 3, …, n + 18}\n"
     ]
    }
   ],
   "source": [
    "n = Symbol('n', integer=True)\n",
    "r = Range(n, n + 20, 3)\n",
    "print(r.inf)\n",
    "pprint(r)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 方法 as_relational(x)\n",
    "\n",
    "在等式和逻辑运算符方面重写一个范围。\n",
    "\n",
    "##### 属性 reversed\n",
    "\n",
    "以相反的顺序返回一个等效范围。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{9, 8, \\ldots, 0\\right\\}$"
      ],
      "text/plain": [
       "Range(9, -1, -1)"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Range\n",
    "Range(10).reversed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### ComplexRegion 复数区域\n",
    "\n",
    "#### 类 class sympy.sets.fancysets.ComplexRegion(sets, polar=False)\n",
    "\n",
    "表示所有复数的集合。它可以用极坐标和直角坐标两种标准形式表示复平面的一个区域。\n",
    "\n",
    "- Polar Form Input 以 ProductSet 或 ProductSet 的 Union 形式表示 r 和 theta 的间隔，并使用标志 Polar = True。\n",
    "\n",
    "$$ Z = \\{z \\in \\mathbb{C} \\mid z = r\\times (\\cos(\\theta) + I\\sin(\\theta)), r \\in [\\texttt{r}], \\theta \\in [\\texttt{theta}]\\} $$\n",
    "\n",
    "- 矩形表单输入的形式是 ProductSet 或 ProductSet 的并，其间隔为 x 和 y，即平面上复数的实部和虚部。默认输入类型为矩形形式。\n",
    "\n",
    "$$ Z = \\{z \\in \\mathbb{C} \\mid z = x + Iy, x \\in [\\operatorname{re}(z)], y \\in [\\operatorname{im}(z)]\\} $$\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{x + y i\\; \\middle|\\; x, y \\in \\left[2, 3\\right] \\times \\left[4, 6\\right] \\right\\}$"
      ],
      "text/plain": [
       "CartesianComplexRegion(ProductSet(Interval(2, 3), Interval(4, 6)))"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import ComplexRegion, Interval, S, I, Union\n",
    "a = Interval(2, 3)\n",
    "b = Interval(4, 6)\n",
    "c1 = ComplexRegion(a*b)  # Rectangular Form\n",
    "c1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- C1表示由四个顶点的坐标(2,4) ，(3,4) ，(3,6)和(2,6)包围的复平面上的矩形区域。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{x + y i\\; \\middle|\\; x, y \\in \\left(\\left[2, 3\\right] \\times \\left[4, 6\\right]\\right) \\cup \\left(\\left[4, 6\\right] \\times \\left[1, 8\\right]\\right) \\right\\}$"
      ],
      "text/plain": [
       "CartesianComplexRegion(Union(ProductSet(Interval(2, 3), Interval(4, 6)), ProductSet(Interval(4, 6), Interval(1, 8))))"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = Interval(1, 8)\n",
    "c2 = ComplexRegion(Union(a*b, b*c))\n",
    "c2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- C2表示复平面上两个矩形区域的并。其中一个被 c1坐标包围，另一个被坐标(4,1) ，(6,1) ，(6,8)和(4,8)包围。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{r \\left(i \\sin{\\left(\\theta \\right)} + \\cos{\\left(\\theta \\right)}\\right)\\; \\middle|\\; r, \\theta \\in \\left[0, 1\\right] \\times \\left[0, 2 \\pi\\right) \\right\\}$"
      ],
      "text/plain": [
       "PolarComplexRegion(ProductSet(Interval(0, 1), Interval.Ropen(0, 2*pi)))"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(2.5 + 4.5*I in c1)\n",
    "print(2.5 + 6.5*I in c1)\n",
    "r = Interval(0, 1)\n",
    "theta = Interval(0, 2*S.Pi)\n",
    "c2 = ComplexRegion(r*theta, polar=True)  # Polar Form\n",
    "c2  # unit Disk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- C2代表以原点为中心的单位圆盘内复平面上的区域。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "PolarComplexRegion(ProductSet(Interval(0, 1), Interval(0, pi)))\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "print(0.5 + 0.5*I in c2)\n",
    "print(1 + 2*I in c2)\n",
    "unit_disk = ComplexRegion(Interval(0, 1)*Interval(0, 2*S.Pi), polar=True)\n",
    "upper_half_unit_disk = ComplexRegion(Interval(0, 1)*Interval(0, S.Pi), polar=True)\n",
    "intersection = unit_disk.intersect(upper_half_unit_disk)\n",
    "print(intersection)\n",
    "print(intersection == upper_half_unit_disk)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 CartesianComplexRegion, PolarComplexRegion, Complexes\n",
    "\n",
    "##### 属性 a_interval\n",
    "\n",
    "返回 `x` 的间隔`intervals`的并集.当`self`是矩形的时候，或者间隔的合并`r`当 `self` 处于极性状态时`polar form`。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(2, 3)\n",
      "Union(Interval(2, 3), Interval(4, 5))\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, ComplexRegion, Union\n",
    "a = Interval(2, 3)\n",
    "b = Interval(4, 5)\n",
    "c = Interval(1, 7)\n",
    "C1 = ComplexRegion(a*b)\n",
    "print(C1.a_interval)\n",
    "C2 = ComplexRegion(Union(a*b, b*c))\n",
    "print(C2.a_interval)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 b_interval\n",
    "\n",
    "返回 `y` 间隔的并当自身是矩形的时候，或者间隔`interval`的并集`theta`  当 `self` 处于极性状态时`polar form`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(4, 5)\n",
      "Interval(1, 7)\n"
     ]
    }
   ],
   "source": [
    "from sympy import Interval, ComplexRegion, Union\n",
    "a = Interval(2, 3)\n",
    "b = Interval(4, 5)\n",
    "c = Interval(1, 7)\n",
    "C1 = ComplexRegion(a*b)\n",
    "print(C1.b_interval)\n",
    "C2 = ComplexRegion(Union(a*b, b*c))\n",
    "print(C2.b_interval)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### classmethod  from_real(sets)\n",
    "\n",
    "将给定的实数子集转换为复数区域。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{x + y i\\; \\middle|\\; x, y \\in \\left[0, 1\\right] \\times \\left\\{0\\right\\} \\right\\}$"
      ],
      "text/plain": [
       "CartesianComplexRegion(ProductSet(Interval(0, 1), {0}))"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval, ComplexRegion\n",
    "unit = Interval(0,1)\n",
    "ComplexRegion.from_real(unit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 psets Pset\n",
    "\n",
    "返回 `self` 的集合(`ProductSets`)输入的元组。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(ProductSet(Interval(2, 3), Interval(4, 5)),)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(ProductSet(Interval(2, 3), Interval(4, 5)),\n",
       " ProductSet(Interval(4, 5), Interval(1, 7)))"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval, ComplexRegion, Union\n",
    "a = Interval(2, 3)\n",
    "b = Interval(4, 5)\n",
    "c = Interval(1, 7)\n",
    "C1 = ComplexRegion(a*b)\n",
    "print(C1.psets)\n",
    "(ProductSet(Interval(2, 3), Interval(4, 5)),)\n",
    "C2 = ComplexRegion(Union(a*b, b*c))\n",
    "C2.psets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 属性 sets 集\n",
    "\n",
    "将原始输入集返回给 `self`。\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ProductSet(Interval(2, 3), Interval(4, 5))\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left(\\left[2, 3\\right] \\times \\left[4, 5\\right]\\right) \\cup \\left(\\left[4, 5\\right] \\times \\left[1, 7\\right]\\right)$"
      ],
      "text/plain": [
       "Union(ProductSet(Interval(2, 3), Interval(4, 5)), ProductSet(Interval(4, 5), Interval(1, 7)))"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import Interval, ComplexRegion, Union\n",
    "a = Interval(2, 3)\n",
    "b = Interval(4, 5)\n",
    "c = Interval(1, 7)\n",
    "C1 = ComplexRegion(a*b)\n",
    "print(C1.sets)\n",
    "C2 = ComplexRegion(Union(a*b, b*c))\n",
    "C2.sets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 类 class sympy.sets.fancysets.CartesianComplexRegion(sets)\n",
    "\n",
    "表示复平面的一个正方形区域的集合。\n",
    "\n",
    "$$ Z = \\{z \\in \\mathbb{C} \\mid z = x + Iy, x \\in [\\operatorname{re}(z)], y \\in [\\operatorname{im}(z)]\\} $$\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import ComplexRegion, I, Interval\n",
    "region = ComplexRegion(Interval(1, 3) * Interval(4, 6))\n",
    "print(2 + 5*I in region)\n",
    "print(5*I in region)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 `ComplexRegion` 复数域, `PolarComplexRegion` 极性复数域, `Complexes` 复数\n",
    "\n",
    "##### 类 class sympy.sets.fancysets.PolarComplexRegion(sets)\n",
    "\n",
    "表示复平面极区的集合。\n",
    "\n",
    "$$ Z = \\{z \\in \\mathbb{C} \\mid z = r\\times (\\cos(\\theta) + I\\sin(\\theta)), r \\in [\\texttt{r}], \\theta \\in [\\texttt{theta}]\\} $$\n",
    "\n",
    "###### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "from sympy import ComplexRegion, Interval, oo, pi, I\n",
    "rset = Interval(0, oo)\n",
    "thetaset = Interval(0, pi)\n",
    "upper_half_plane = ComplexRegion(rset * thetaset, polar=True)\n",
    "print(1 + I in upper_half_plane)\n",
    "print(1 - I in upper_half_plane)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> 参见 `ComplexRegion`, `CartesianComplexRegion`, `Complexes`\n",
    "\n",
    "#### sympy.sets.fancysets.normalize_theta_set(theta)\n",
    "Normalize a Real Set  in the interval . It returns a normalized value of theta in the Set. For Interval, a maximum of one cycle , is returned i.e. for theta equal to , returned normalized value would be . As of now intervals with end points as non-multiples of pi is not supported.\n",
    "\n",
    "标准化一个实集 `θ` 在区间 [0,2π)。它返回集合中的一个标准化值 θ。对于间隔，最大值为一个循环[0,2 π ]，返回，例如当 θ 等于\n",
    "[0,10 π]，返回的规范化值为[0,2π]. 现在不支持终点为 π 的非倍数的时间间隔。\n",
    "\n",
    "##### 异常\n",
    "\n",
    "- NotImplementedError 尚未实现异常: 对 θ 集进行规范化的算法还没有实现。\n",
    "\n",
    "- ValueError 值错误: 输入无效，即输入不是一个真正的集合。\n",
    "\n",
    "- RuntimeError: 这是一个 bug，请向 github 问题跟踪器报告。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Interval(pi/2, pi)\n",
      "Interval.Ropen(0, 2*pi)\n",
      "Union(Interval(0, pi/2), Interval.Ropen(3*pi/2, 2*pi))\n",
      "Interval.Ropen(0, 2*pi)\n",
      "Interval(pi/2, 3*pi/2)\n",
      "{0, pi}\n"
     ]
    }
   ],
   "source": [
    "from sympy.sets.fancysets import normalize_theta_set\n",
    "from sympy import Interval, FiniteSet, pi\n",
    "print(normalize_theta_set(Interval(9*pi/2, 5*pi)))\n",
    "print(normalize_theta_set(Interval(-3*pi/2, pi/2)))\n",
    "print(normalize_theta_set(Interval(-pi/2, pi/2)))\n",
    "print(normalize_theta_set(Interval(-4*pi, 3*pi)))\n",
    "print(normalize_theta_set(Interval(-3*pi/2, -pi/2)))\n",
    "print(normalize_theta_set(FiniteSet(0, pi, 3*pi)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Power sets 幂集集\n",
    "\n",
    "### PowerSet 幂集\n",
    "\n",
    "#### 类 class sympy.sets.powerset.PowerSet(arg, evaluate=None)\n",
    "\n",
    "代表一个幂集的符号对象。\n",
    "\n",
    "##### Parameters 参数\n",
    "\n",
    "- arg : Set\n",
    "\n",
    "The set to take power of.\n",
    "\n",
    "获取`power`运算的集合。\n",
    "\n",
    "- evaluate : bool\n",
    "\n",
    "控制计算的标志。\n",
    "\n",
    "如果对有限集合禁用求值，则可以利用子集测试作为隶属度测试。\n",
    "\n",
    "##### 注释\n",
    "\n",
    "幂集 $\\mathcal{P}(S)$ 被定义为包含 $S$ 的所有子集的集合。\n",
    "\n",
    "如果集合 `S` 是一个有限集合，那么它的幂集将有 $2^{\\left| S \\right|}$ 元素，其中$\\left| S \\right|$表示 S 的基数。\n",
    "\n",
    "##### 例子\n",
    "\n",
    "有限集的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathcal{P}\\left(\\left\\{1, 2, 3\\right\\}\\right)$"
      ],
      "text/plain": [
       "PowerSet({1, 2, 3})"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sympy import PowerSet, S, FiniteSet\n",
    "PowerSet(FiniteSet(1, 2, 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "空集的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathcal{P}\\left(\\emptyset\\right)$"
      ],
      "text/plain": [
       "PowerSet(EmptySet)"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "PowerSet(S.EmptySet)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathcal{P}\\left(\\mathcal{P}\\left(\\emptyset\\right)\\right)$"
      ],
      "text/plain": [
       "PowerSet(PowerSet(EmptySet))"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "PowerSet(PowerSet(S.EmptySet))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "无限集的幂集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathcal{P}\\left(\\mathbb{R}\\right)$"
      ],
      "text/plain": [
       "PowerSet(Reals)"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "PowerSet(S.Reals)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将有限集的幂集计算到它的显式形式:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{\\emptyset, \\left\\{1\\right\\}, \\left\\{2\\right\\}, \\left\\{3\\right\\}, \\left\\{1, 2\\right\\}, \\left\\{1, 3\\right\\}, \\left\\{2, 3\\right\\}, \\left\\{1, 2, 3\\right\\}\\right\\}$"
      ],
      "text/plain": [
       "FiniteSet(EmptySet, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3})"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "PowerSet(FiniteSet(1, 2, 3)).rewrite(FiniteSet)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 参考资料\n",
    "\n",
    "[R751] https://en.wikipedia.org/wiki/Power_set\n",
    "\n",
    "[R752] https://en.wikipedia.org/wiki/Axiom_of_power_set\n",
    "\n",
    "### Iteration over sets 集合上的迭代\n",
    "\n",
    "对于集合的并集运算，$\\{a, b\\} \\cup \\{x, y\\}$ 可以被处理为 $\\{a, b, x, y\\}$ 用于迭代而不用考虑元素的独特性； 然而，对于交集运算 $\\{a, b\\} \\cap \\{x, y\\}$ 为 $\\varnothing$ 或者 $\\{a, b \\}$ 并不总是确定的， 因为某些a, b, x或者y可能并不是交集的一部分。\n",
    "\n",
    "迭代一个集合的元素，包括集合的交集、补集或对称差集的元素(可能是重复的) ，前提是所有元素都是集合的元素。如果任何元素不能被确定为一个集合的成员，那么迭代给出 `TypeError`。在 `x` 在 `y` 中会产生错误的情况下也会发生这种情况。\n",
    "\n",
    "这样实现有一些原因，即使它破坏了 python set 迭代器工作方式的一致性。我们记住，从现有sympy符号集合像 `FiniteSet (* s)`这样的sympy符号集合可能是一种常见的用法。这种方法将使得 `FiniteSet (* s)`与任何符号集处理方法(如 `FiniteSet (* simplify (s)))`一致。\n",
    "\n",
    "## Condition Sets 条件集集合\n",
    "\n",
    "### ConditionSet 条件集\n",
    "\n",
    "#### 类 class sympy.sets.conditionset.ConditionSet(sym, condition, base_set=UniversalSet)\n",
    "\n",
    "满足给定条件的一组元素。\n",
    "\n",
    "$$\\{x \\mid \\textrm{condition}(x) = \\texttt{True}, x \\in S\\}$$\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "from sympy import Symbol, S, ConditionSet, pi, Eq, sin, Interval\n",
    "from sympy.abc import x, y, z\n",
    "sin_sols = ConditionSet(x, Eq(sin(x), 0), Interval(0, 2*pi))\n",
    "print(2*pi in sin_sols)\n",
    "print(pi/2 in sin_sols)\n",
    "print(3*pi in sin_sols)\n",
    "print(5 in ConditionSet(x, x**2 > 4, S.Reals))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果该值不在基集中，则结果为 false:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 注释\n",
    "\n",
    "应避免使用带有假设的符号，否则条件可能不考虑集合的情况而作出评价:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\emptyset$"
      ],
      "text/plain": [
       "EmptySet"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "n = Symbol('n', negative=True)\n",
    "cond = (n > 0)\n",
    "print(cond)\n",
    "ConditionSet(n, cond, S.Integers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "只有自由的符号可以改变使用`subs`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{x\\; \\middle|\\; x \\in \\left\\{y, z\\right\\} \\wedge x < 1 \\right\\}$"
      ],
      "text/plain": [
       "ConditionSet(x, x < 1, {y, z})"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c = ConditionSet(x, x < 1, {x, z})\n",
    "c.subs(x, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果没有指定基集，则暗示通用集:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\mathbb{U}$"
      ],
      "text/plain": [
       "UniversalSet"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ConditionSet(x, x < 1).base_set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "只能使用符号或类似符号的表达式:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "ename": "ValueError",
     "evalue": "`x + 1` is not symbol-like",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "Input \u001b[0;32mIn [72]\u001b[0m, in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mConditionSet\u001b[49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mx\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m<\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mS\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mIntegers\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/.local/lib/python3.9/site-packages/sympy/sets/conditionset.py:134\u001b[0m, in \u001b[0;36mConditionSet.__new__\u001b[0;34m(cls, sym, condition, base_set)\u001b[0m\n\u001b[1;32m    132\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m flat:\n\u001b[1;32m    133\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28mgetattr\u001b[39m(i, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m_diff_wrt\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;28;01mFalse\u001b[39;00m):\n\u001b[0;32m--> 134\u001b[0m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m`\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m` is not symbol-like\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m i)\n\u001b[1;32m    136\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m base_set\u001b[38;5;241m.\u001b[39mcontains(sym) \u001b[38;5;129;01mis\u001b[39;00m S\u001b[38;5;241m.\u001b[39mfalse:\n\u001b[1;32m    137\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124msym `\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m` is not in base_set `\u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m`\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;241m%\u001b[39m (sym, base_set))\n",
      "\u001b[0;31mValueError\u001b[0m: `x + 1` is not symbol-like"
     ]
    }
   ],
   "source": [
    "\n",
    "ConditionSet(x + 1, x + 1 < 1, S.Integers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当基本集是一个 `ConditionSet` 时，如果可能的话，符号将被统一，并优先选择最外面的符号:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/latex": [
       "$\\displaystyle \\left\\{x\\; \\middle|\\; x \\in \\mathbb{Z} \\wedge x < y \\wedge x + y < 2 \\right\\}$"
      ],
      "text/plain": [
       "ConditionSet(x, (x < y) & (x + y < 2), Integers)"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ConditionSet(x, x < y, ConditionSet(z, z + y < 2, S.Integers))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Relations on sets 集合上的关系\n",
    "\n",
    "#### 类 class sympy.sets.conditionset.Contains(x, s)\n",
    "\n",
    "断言 `x` 是集合 `S` 的元素。\n",
    "\n",
    "##### 例子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "Contains(i, Naturals)\n"
     ]
    }
   ],
   "source": [
    "from sympy import Symbol, Integer, S, Contains\n",
    "print(Contains(Integer(2), S.Integers))\n",
    "print(Contains(Integer(-2), S.Naturals))\n",
    "i = Symbol('i', integer=True)\n",
    "print(Contains(i, S.Naturals))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### 参考资料\n",
    "\n",
    "[R753] https://en.wikipedia.org/wiki/Element_%28mathematics%29"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a"
  },
  "kernelspec": {
   "display_name": "Python 3.9.5 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
